"""
文件读写操作
open(filename, mode)
filename：包含了你要访问的文件名称的字符串值。
mode：决定了打开文件的模式：只读，写入，追加等。所有可取值见如下的完全列表。这个参数是非强制的，默认文件访问模式为只读(r)

常用的mode参数值
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式
rb	以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头
r+	打开一个文件用于读写。文件指针将会放在文件的开头
rb+	以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w	打开一个文件只用于写入。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件
wb	以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件。
w+	打开一个文件用于读写。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件
wb+	以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件。
a	打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。也就是说，新的内容将会被写入到已有内容之后。如果该文件不存在，创建新文件进行写入
ab	以二进制格式打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。也就是说，新的内容将会被写入到已有内容之后。如果该文件不存在，创建新文件进行写入。
a+	打开一个文件用于读写。如果该文件已存在，文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在，创建新文件用于读写
ab+	以二进制格式打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。如果该文件不存在，创建新文件用于读写

f.seek()
如果要改变文件指针当前的位置, 可以使用 f.seek(offset, from_what) 函数。

from_what 的值, 如果是 0 表示开头, 如果是 1 表示当前位置, 2 表示文件的结尾，例如：

seek(x,0) ： 从起始位置即文件首行首字符开始移动 x 个字符
seek(x,1) ： 表示从当前位置往后移动x个字符     需要结合二进制模式读取rb,ab+等
seek(-x,2)：表示从文件的结尾往前移动x个字符
from_what 值为默认为0，即文件开头

"""

import pickle


def format1():
    a = 'aaa'
    n1 = 10
    n2 = 2
    print(type(str(a)))
    print(f'repr = {type(repr(a))}')
    print(f'将字符串靠右, 并在左边填充空格 n1*n2 : {repr(n1).rjust(1)} * {repr(n2).rjust(1)} = {repr(n1 * n2).rjust(3)}')
    s1 = '100'
    print(f'zfill(x) 包含填充的0 总计x个字符  {s1.zfill(5)} ,{"-1.01".zfill(7)} ,{"3.1415".zfill(7)}')

    #: 后传入一个整数, 可以保证该域至少有这么多的宽度。 用于美化表格时很有用
    print(f'5个宽度:{"{0:5}".format(3.1)}, 保留3位小数 : {"{0:.3f}".format(3.1415926)}')


def input1():
    s1 = input("请输入:")
    print(f'你输入的内容:{s1}')


# 文件操作 读取
def file_read():
    # 只读方式，只可读取文件,注意文件的编码格式
    f = open("doc/testfile.txt", "r", encoding="utf-8")

    # 为了读取一个文件的内容 调用 f.read(size), 当 size 被忽略了或者为负, 那么该文件的所有内容都将被读取并且返回
    # text = f.read()

    # f.readline(size) 会从文件中读取单独的一行，size 不传参则读取整行，size为该行字符数量。
    # 换行符为 '\n'。f.readline() 如果返回一个空字符串, 说明已经已经读取到最后一行
    print(f'读取第一行内容: {f.readline(2)}')

    linenum = 1
    for line in f:
        print(f'第{linenum}行 : {line}', end='')
        linenum += 1

    # 关闭打开的文件
    f.close()


# 文件操作 读取 演示read() seek()方法
def file_read2():
    # 只读方式，只可读取文件,注意文件的编码格式
    f = open("doc/testfile.txt", "r", encoding="utf-8")

    # 为了读取一个文件的内容 调用 f.read(size), 当 size 被忽略了或者为负, 那么该文件的所有内容都将被读取并且返回

    # 返回文件对象当前所处的位置, 它是从文件开头开始算起的字节数,中文占有3个字节,英文占用1个字节
    print(f'读写位置:{f.tell()}')  # 默认开始位置是0，
    text = f.read(1)
    print(f'读取第一个字符内容: {text} 位置:{f.tell()}')  # 如果第一个文字是中文，这里tell()是3

    f.seek(6)  # 读写位置 跳转到第6个字节地方，也就是第二个中文后面
    print(f'读到的内容：{f.read(1)}  读写位置:{f.tell()}')

    # 关闭打开的文件
    f.close()


# 文件操作 写
def file_write():
    # 写文件 ，w模式会清空原有文件内容,然后写入新内容， 不清空文件选择最佳内容，这选择a模式
    # f = open("doc/testfile.txt", "w",encoding="utf-8")
    f = open("doc/testfile.txt", "a", encoding="utf-8")

    # f.write("写入整篇内容")
    f.writelines("\n先换行 再追加一行内容")
    # f.writelines("新写入一行试试")

    # 关闭打开的文件
    f.close()


# 文件操作 序列化后写入文件 pickle模块实现了基本的数据序列和反序列化
def file_write_seri():
    # 写文件 ，序列化操作需要使用二进制方式读写文件,所以这里写入模式选择wb
    f = open("doc/pickle_test.txt", "wb+")

    arr = list(range(1, 10))
    pickle.dump(arr, f)  # 将一个列表写入文件

    # 重置文件指针位置到开始，然后方便重新读写文件，否则报错
    f.seek(0)

    # 取出序列化的列表
    x = pickle.load(f)

    print(f'x = {x}')

    # 关闭打开的文件
    f.close()


if __name__ == '__main__':
    # format1()
    # input1()
    # file_read()
    # file_write()
    # file_read2()
    file_write_seri()
